﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.LIB;
using YArchitech.Revit;

namespace HYFloorPipeModule
{
	public class FloorPipeMarkingTool
	{
		public static void DrawMarksToTheFloorPipes(Document doc, XYZ ep, double length, double distance)
		{
			List<Element> elems = new List<Element>();
			FloorPipeMarkingTool.DrawTheRetangleOfMarks(doc, ep, length, distance, ref elems);
			doc.Regenerate();
			FloorPipeMarkingTool.CreateGroup(elems, doc);
		}

		public static List<Element> DrawTheRetangleOfMarks(Document doc, XYZ ep, double length, double distance, ref List<Element> elems)
		{
			List<double> floorPipeMarkSizes = RevitDocumentExtension.GetFloorPipeMarkSizes();
			double num = floorPipeMarkSizes[0] / 304.8;
			XYZ xyz = new XYZ(ep.X, ep.Y + num, ep.Z);
			XYZ xyz2 = new XYZ(ep.X + 2.0 * num, xyz.Y, ep.Z);
			XYZ xyz3 = new XYZ(xyz2.X, ep.Y, ep.Z);
			elems.Add(YJKRevitTools.DrawDetailLine(doc, ep, xyz));
			elems.Add(YJKRevitTools.DrawDetailLine(doc, xyz, xyz2));
			elems.Add(YJKRevitTools.DrawDetailLine(doc, xyz2, xyz3));
			elems.Add(YJKRevitTools.DrawDetailLine(doc, xyz3, ep));
			XYZ origin = new XYZ(ep.X + floorPipeMarkSizes[1] / 304.8, ep.Y + floorPipeMarkSizes[2] / 304.8, ep.Z);
			XYZ origin2 = new XYZ(ep.X + floorPipeMarkSizes[1] / 304.8, ep.Y + floorPipeMarkSizes[3] / 304.8, ep.Z);
			string strText = "长度:" + Math.Round(length, 1) + "m";
			string strText2 = "间距:" + Math.Round(distance) + "mm";
            TextNote textNode = doc.GetTextNode(doc.ActiveView, origin, new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), 0.0, (TextAlignFlags)64, strText, floorPipeMarkSizes[4]);
			textNode.TextNoteType = FloorPipeMarkingTool.ChangeTextNodeType(textNode);
			elems.Add(textNode);
            TextNote textNode2 = doc.GetTextNode(doc.ActiveView, origin2, new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), 0.0, (TextAlignFlags)64, strText2, floorPipeMarkSizes[4]);
			textNode2.TextNoteType = FloorPipeMarkingTool.ChangeTextNodeType(textNode2);
			elems.Add(textNode2);
			return elems;
		}

		public static void DrawMarksToTheFloorPipes(Document doc, XYZ sp, XYZ ep, double length, double distance)
		{
			List<Element> list = new List<Element>();
			list.Add(YJKRevitTools.DrawDetailLine(doc, sp, ep));
			FloorPipeMarkingTool.DrawTheRetangleOfMarks(doc, ep, length, distance, ref list);
			doc.Regenerate();
			FloorPipeMarkingTool.CreateGroup(list, doc);
		}

		public static void MarkFloorPipes(Document doc, XYZ startPnt, XYZ endPnt, double length, double distance, QuadrantLocation pointQuadrant)
		{
			List<Element> list = new List<Element>();
			DetailLine item = YJKRevitTools.DrawDetailLine(doc, startPnt, endPnt);
			list.Add(item);
			XYZ upDirection = doc.ActiveView.UpDirection;
			XYZ rightDirection = doc.ActiveView.RightDirection;
			string text = "长度:" + Math.Round(length, 1) + "m";
			string text2 = "间距:" + Math.Round(distance) + "mm";
			bool flag = StringTools.GetStringByteLength(text) > StringTools.GetStringByteLength(text2);
			SubTransaction subTransaction = new SubTransaction(doc);
			YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
			try
			{
				subTransaction.Start();
				TextNoteType textNoteType = FloorPipeMarkingTool.ChangeTextNodeType(doc);
				TextNote textNote = UnifiedModified.HYCreatTextNote(doc, text, endPnt, textNoteType);
				TextNote textNote2 = UnifiedModified.HYCreatTextNote(doc, text2, endPnt, textNoteType);
				doc.Regenerate();
				double num = (double)doc.ActiveView.Scale;
				double num2 = textNote.Height * num;
				double num3 = UnifiedModified.GetTextNoteWidth(doc, textNote) * 1.05;
				num3 = (flag ? (UnifiedModified.GetTextNoteWidth(doc, textNote) * 1.05) : (UnifiedModified.GetTextNoteWidth(doc, textNote2) * 1.05));
				if (int.Parse(RevitVersion.Version) <= 2015)
				{
					num3 *= 100.0;
				}
				list.Add(textNote);
				list.Add(textNote2);
				subTransaction.Commit();
				List<XYZ> drawRectanglePoints = FloorPipeMarkingTool.GetDrawRectanglePoints(endPnt, pointQuadrant, doc, num3, 2.0 * num2);
				if (RevitVersion.Version == "2015")
				{
					endPnt = endPnt.Add(num2 / 2.0 * doc.ActiveView.UpDirection);
				}
				XYZ moveVector = drawRectanglePoints[0].Subtract(endPnt);
				hyrotateFamilyInstance.MoveElement(moveVector, textNote);
				XYZ moveVector2 = (drawRectanglePoints[0].Add(drawRectanglePoints[1]) / 2.0).Subtract(endPnt);
				hyrotateFamilyInstance.MoveElement(moveVector2, textNote2);
				FloorPipeMarkingTool.CreatRectangleLines(doc, drawRectanglePoints, ref list);
				doc.Regenerate();
				FloorPipeMarkingTool.CreateGroup(list, doc);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
                if (subTransaction != null && (int)subTransaction.GetStatus() == 1)
				{
					subTransaction.RollBack();
				}
			}
		}

		public static List<XYZ> GetDrawRectanglePoints(XYZ screenStartPnt, QuadrantLocation pointQuadrant, Document doc, double hLineLength, double vLineLength)
		{
			List<XYZ> list = new List<XYZ>();
			View activeView = doc.ActiveView;
			XYZ xyz = null;
			XYZ xyz2 = null;
			switch (pointQuadrant)
			{
			case QuadrantLocation.First:
				xyz2 = screenStartPnt.Add(vLineLength * activeView.UpDirection);
				xyz = screenStartPnt;
				break;
			case QuadrantLocation.Second:
				xyz2 = screenStartPnt;
				xyz = screenStartPnt.Subtract(vLineLength * activeView.UpDirection);
				break;
			case QuadrantLocation.Third:
				xyz2 = screenStartPnt.Subtract(hLineLength * activeView.RightDirection);
				xyz = xyz2.Subtract(vLineLength * activeView.UpDirection);
				break;
			case QuadrantLocation.Fourth:
				xyz2 = screenStartPnt.Subtract(hLineLength * activeView.RightDirection);
				xyz2 = xyz2.Add(vLineLength * activeView.UpDirection);
				xyz = xyz2.Subtract(vLineLength * activeView.UpDirection);
				break;
			case QuadrantLocation.XPosition:
				pointQuadrant = QuadrantLocation.XPosition;
				xyz2 = screenStartPnt.Add(vLineLength / 2.0 * activeView.UpDirection);
				xyz = screenStartPnt.Subtract(vLineLength / 2.0 * activeView.UpDirection);
				break;
			case QuadrantLocation.YNegative:
				xyz2 = screenStartPnt.Subtract(hLineLength / 2.0 * activeView.RightDirection);
				xyz = xyz2.Subtract(vLineLength * activeView.UpDirection);
				break;
			case QuadrantLocation.XNegative:
				xyz2 = screenStartPnt.Subtract(hLineLength * activeView.RightDirection);
				xyz2 = xyz2.Add(vLineLength / 2.0 * activeView.UpDirection);
				xyz = xyz2.Subtract(vLineLength * activeView.UpDirection);
				break;
			case QuadrantLocation.YPosition:
				xyz2 = screenStartPnt.Subtract(hLineLength / 2.0 * activeView.RightDirection);
				xyz2 = xyz2.Add(vLineLength * activeView.UpDirection);
				xyz = xyz2.Subtract(vLineLength * activeView.UpDirection);
				break;
			}
			XYZ item = xyz.Add(hLineLength * activeView.RightDirection);
			XYZ item2 = xyz2.Add(hLineLength * activeView.RightDirection);
			list.Add(xyz2);
			list.Add(xyz);
			list.Add(item);
			list.Add(item2);
			return list;
		}

		private static void CreatRectangleLines(Document doc, XYZ startPnt, double width, double height, ref List<Element> elems)
		{
			XYZ upDirection = doc.ActiveView.UpDirection;
			XYZ rightDirection = doc.ActiveView.RightDirection;
			XYZ xyz = startPnt.Subtract(-1.0 * height * upDirection);
			XYZ sPoint = xyz.Add(width * rightDirection);
			XYZ ePoint = startPnt.Add(width * rightDirection);
			DetailLine item = YJKRevitTools.DrawDetailLine(doc, startPnt, xyz);
			elems.Add(item);
			DetailLine item2 = YJKRevitTools.DrawDetailLine(doc, sPoint, xyz);
			elems.Add(item2);
			DetailLine item3 = YJKRevitTools.DrawDetailLine(doc, sPoint, ePoint);
			elems.Add(item3);
			DetailLine item4 = YJKRevitTools.DrawDetailLine(doc, startPnt, ePoint);
			elems.Add(item4);
		}

		public static void CreatRectangleLines(Document doc, List<XYZ> listPoint, ref List<Element> elems)
		{
			if (listPoint == null || listPoint.Count != 4)
			{
				return;
			}
			DetailLine item = YJKRevitTools.DrawDetailLine(doc, listPoint[0], listPoint[1]);
			elems.Add(item);
			DetailLine item2 = YJKRevitTools.DrawDetailLine(doc, listPoint[1], listPoint[2]);
			elems.Add(item2);
			DetailLine item3 = YJKRevitTools.DrawDetailLine(doc, listPoint[2], listPoint[3]);
			elems.Add(item3);
			DetailLine item4 = YJKRevitTools.DrawDetailLine(doc, listPoint[3], listPoint[0]);
			elems.Add(item4);
		}

		public static void CreateGroup(List<Element> elems, Document doc)
		{
			ElementSet elementSet = new ElementSet();
			foreach (Element element in elems)
			{
				if (element != null)
				{
					elementSet.Insert(element);
				}
			}
			doc.CreatYJKGroup(elementSet);
		}

		public static TextNoteType ChangeTextNodeType(TextNote tn)
		{
			foreach (Element element in new FilteredElementCollector(tn.Document).OfClass(typeof(TextNoteType)).ToElements())
			{
				if (element.Name.Equals("HY-仿宋-3.0-0.7") || element.Name.Equals("HY-仿宋-3-0.7"))
				{
					return element as TextNoteType;
				}
			}
			string text = "HY-仿宋-3.0-0.7";
			TextNoteType textNoteType = tn.TextNoteType.Duplicate(text) as TextNoteType;
			textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set("仿宋");
			textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(0.00984251968503937);
			textNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_BOLD).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_ITALIC).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_UNDERLINE).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(0.7);
			textNoteType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_BACKGROUND).Set(1);
			return textNoteType;
		}

		public static TextNoteType ChangeTextNodeType(Document doc)
		{
			ICollection<Element> collection = new FilteredElementCollector(doc).OfClass(typeof(TextNoteType)).ToElements();
			foreach (Element element in collection)
			{
				if (element.Name.Equals("HY-仿宋-3.0-0.7") || element.Name.Equals("HY-仿宋-3-0.7"))
				{
					return element as TextNoteType;
				}
			}
			string text = "HY-仿宋-3.0-0.7";
			TextNoteType textNoteType = (collection.First<Element>() as TextNoteType).Duplicate(text) as TextNoteType;
			textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set("仿宋");
			textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(0.00984251968503937);
			textNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_BOLD).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_ITALIC).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_STYLE_UNDERLINE).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(0.7);
			textNoteType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(0);
			textNoteType.get_Parameter(BuiltInParameter.TEXT_BACKGROUND).Set(1);
			return textNoteType;
		}
	}
}
